package org.ethan.user.service.impl;

import org.ethan.basic.exception.BasicException;
import org.ethan.basic.util.StrUtils;
import org.ethan.user.constant.UserConst;
import org.ethan.user.domain.User;
import org.ethan.user.mapper.UserMapper;
import org.ethan.user.service.IVerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;


/**
 * 用户注册时发送短信验证码的流程
 * 1.校验
 *  1.1 手机号不能为空
 *  1.2 手机号是否被注册 查询t_user表
 * 2.判断验证码是否有效（3分钟），从redis中是否能拿到 key： business_register:15982495855
 *  2.1 如果拿到了 需要判断是否过了1分钟重发时间      value:  9527:14679321341313
 *   2.1.1 如果没有过重发时间,报错：请勿重发获取验证码  1*60*1000
 *   2.1.2 如果过了，使用上次的验证码====
 *  2.2 如果拿不到
 *   2.2.1 直接生成新的验证码  ===
 * 3.存储redis 设置3分钟过期
 * 4.发送短信通知客人 验证码是：9527 请在3分钟内使用
 *
 */
@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private UserMapper mapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void verifyCode(Map<String, String> map) {
        String phone = map.get("phone");
        String type = map.get("type");
        String redisKey = "";

        // 判断
        // 1. 手机号不能为空
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)){
            throw new BasicException("手机不能为空。。。");
        }

        if(type.equals("register")){ // 注册流程
            // 2. 手机号是否已存在  t_user
            User user = mapper.findByPhone(phone);
            if (user!=null) {
                throw new BasicException("手机号已注册。。。");
            }
            redisKey = UserConst.REGISTER_PREFIX + phone;
            sendCode(redisKey);
        } else if (type.equals("binder")){ // 绑定流程
            redisKey = UserConst.BINDER_PREFIX + phone;
            sendCode(redisKey);
        }
    }

    /**
     * 发送验证码校验
     * @param redisKey
     */
    public void sendCode(String redisKey){
        // 3. 三分中过期， 从redis中取，如果能取到，没有过期
        // key: 业务标识+手机号    register_prefix+phone
        Object tmpCode = redisTemplate.opsForValue().get(redisKey);

        String code = null;
        if(tmpCode != null){
            // 3.1. 判断当前验证码是否超过一分钟，没有超过一分钟，直接提示：验证码已发送，请勿重复发送。。。
            // 获取时间戳
            String time = tmpCode.toString().split(":")[0];

            if(System.currentTimeMillis() - Long.parseLong(time) <= 60 * 1000){    // value: 时间戳+":"+code      65468731654654+":"+code
                throw new BasicException("验证码已发送，请勿重新发送。。。");
            }else{
                // 3.2. 超过一分钟，重新刷新之前验证码的过期时间
                code = tmpCode.toString().split(":")[1];
            }
        } else {
            // 4. 如果取不到， 从新生成验证码，
            code = StrUtils.getComplexRandomString(6);
        }
        redisTemplate.opsForValue().set(redisKey,
                System.currentTimeMillis()+":"+code,
                3L,
                TimeUnit.MINUTES);

        // SendMsg.sendSMS(phone, "验证码:"+code+",请三分中内使用");
        System.out.println(code);
    }
}
